﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EnvDTE;
using System.IO;
using LogoGenerator;
using System.Windows;
using System.Windows.Media.Imaging;
using Microsoft.VisualStudio.TemplateWizard;
using System.Windows.Media;

namespace RssReaderTemplate.Wizard
{
    public abstract class WizardBase : ICanRun
    {
        protected TemplateParameters _templateParameters = new TemplateParameters();
        protected DTE _dte;
        protected string _projectDirectory;

        public TemplateParameters TemplateParameters
        {
            get { return _templateParameters; }
            set { _templateParameters = value; }
        }


        public virtual void BeforeOpeningFile(ProjectItem projectItem)
        {
        }

        public virtual void ProjectFinishedGenerating(Project project)
        {
        }

        public virtual void ProjectItemFinishedGenerating(ProjectItem projectItem)
        {
        }

        public virtual void RunStarted(object automationObject, Dictionary<string, string> replacementsDictionary, WizardRunKind runKind, object[] customParams)
        {
            _dte = automationObject as DTE;
            _projectDirectory = replacementsDictionary["$destinationdirectory$"];            
        }

        protected void AddParameters(Dictionary<string, string> replacementsDictionary)
        {
            replacementsDictionary.Add("$TemplateRssUrl$", TemplateParameters.RssUrl);
            replacementsDictionary.Add("$TemplateApplicationName$", TemplateParameters.ApplicationName);
            replacementsDictionary.Add("_TemplateSafeApplicationName_", TemplateParameters.ApplicationName.Replace(" ", ""));
            replacementsDictionary.Add("RssReaderTemplate", TemplateParameters.ApplicationName.Replace(" ", ""));
            replacementsDictionary.Add("_TemplateApplicationAuthor_", TemplateParameters.ApplicationAuthor);
            replacementsDictionary.Add("_TemplateApplicationEmail_", TemplateParameters.ApplicationEmail);
            replacementsDictionary.Add("_TemplateApplicationContactWebpage_", TemplateParameters.ApplicationContactWebpage);
            replacementsDictionary.Add("_TemplateApplicationRssWebpage_", TemplateParameters.ApplicationContactRssWebpage);
        }

        public virtual bool ShouldAddProjectItem(string filePath)
        {
            return true;
        }

        public virtual void RunFinished()
        {

            GenerateLogos(TemplateParameters.ApplicationName.Replace(" ", ""));
            BuildSolution();
            RunSolution();
            PackageForDeployment();
        }

        private void RunSolution()
        {
            _dte.Solution.SolutionBuild.Deploy(true);
            _dte.Solution.SolutionBuild.Run();
        }

        private void PackageForDeployment()
        {
            string deploymentDirectory = Path.Combine(_projectDirectory,"Deployment");
            DirectoryInfo depDir = Directory.CreateDirectory(deploymentDirectory);
            string compilationDirectory = Path.Combine(_projectDirectory, "Bin", "Release");
            DirectoryInfo compDir = new DirectoryInfo(compilationDirectory);
            DirectoryInfo projDir = new DirectoryInfo(_projectDirectory);
            var images = projDir.GetFiles("*x*.png");
            foreach (var item in images)
            {
                item.MoveTo(Path.Combine(deploymentDirectory,item.Name));
            }
            var xap = compDir.GetFiles("*.xap").Single();
            xap.MoveTo(Path.Combine(deploymentDirectory,xap.Name));
        }

        private void GenerateLogos(string logoText)
        {
            Tuple<int, int>[] sizes = new Tuple<int, int>[]{
                Tuple.Create(200,200),
                Tuple.Create(173,173),
                Tuple.Create(99,99)
            };
            foreach (var size in sizes)
            {
                GenerateImage(logoText, size);
            }
            GenerateImage(logoText, Tuple.Create(63, 63), Path.Combine(_projectDirectory, "ApplicationIcon.png"));
            GenerateImage(logoText, Tuple.Create(173, 173), Path.Combine(_projectDirectory, "Background.png"));
        }

        private void BuildSolution()
        {
            _dte.Solution
                .SolutionBuild
                .SolutionConfigurations
                .OfType<SolutionConfiguration>()
                .Single(x => x.Name == "Release")
                .Activate();
            _dte.Solution.SolutionBuild.Build(true);
        }

        private void GenerateImage(string logoText, Tuple<int, int> size, string fileName = null)
        {
            Logo grid = CreateLogo(logoText, size.Item1, size.Item2);
            if (fileName == null)
            {
                fileName = Path.Combine(_projectDirectory, string.Format("{0}{1}x{2}.png", logoText, size.Item1, size.Item2));
            }
            SaveImage(grid, size.Item1, size.Item2, fileName);
        }

        private static Logo CreateLogo(string logoText, int height, int width)
        {
            Logo logo = new Logo();
            logo.Text = logoText;
            return logo;
        }

        static void SaveImage(UIElement element, int height, int width, string name)
        {
            //control to render
            element.Measure(new Size(height, width));
            element.Arrange(new Rect(0, 0, height, width));
            element.UpdateLayout();
            RenderTargetBitmap bmp = new RenderTargetBitmap(height, width, 96, 96, PixelFormats.Pbgra32);
            bmp.Render(element);
            BitmapEncoder encoder;
            encoder = new PngBitmapEncoder();
            encoder.Frames.Add(BitmapFrame.Create(bmp));
            using (Stream stm = File.Create(name)) { encoder.Save(stm); }
        }

        public virtual bool CanRun
        {
            get { return false; }
        }
    }
}
